﻿namespace Server
{
    using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.ServiceModel;
    using System.Web;
    using ServerApp;
    using ServerApp.DAL;
    using ServerApp.AdditionalClasses.External;

    [ServiceBehavior(InstanceContextMode = InstanceContextMode.Single)]
    public class AppService : IAppService
    {

        #region Order

        /// <summary>
        /// Sends order (used by customer or manager) 
        /// </summary>
        /// <param name="custumerId">Id of the customer</param>
        /// <param name="products">Dictionary of the products [productId - count]</param>
        /// <param name="placeId">Id place of the order destination</param>
        /// <param name="whoProcessId">Id of the ecxecutor. If 0 - order is free</param>
        /// <returns>new value of the OrderView</returns>
        public OrderFull SetOrder(long? custumerId, Dictionary<long, int> products, int placeId, long? whoProcessId = 0)
        {
            return ServerApp.DAL.OrderService.SaveOrder(custumerId, products, placeId, whoProcessId);
        }

        /// <summary>
        /// Gets the history of the orders of the one customer
        /// </summary>
        /// <param name="custumerId">customer id</param>
        /// <param name="count">count of the orders for review</param>
        /// <returns>list of the OrderView objects</returns>
        public List<OrderView> GetOrderHistory(long custumerId, int count)
        {
            return ServerApp.DAL.OrderService.GetOrderHistory(custumerId, count);
        }

        /// <summary>
        /// Gets the list of the orders views
        /// </summary>        
        /// <param name="page">Number of the page</param>        
        /// <param name="filter">Dictionary<OrderFilter.value,object></param>
        /// <param name="numberOnThePage">Number of the orders on the one page</param>
        /// <returns>list of the orderView</returns>   
        public List<OrderView> GetOrderList(Dictionary<OrderFilter, object> filter, int page, int numberOnThePage)
        {
            return ServerApp.DAL.OrderService.GetOrderList(filter, page, numberOnThePage);
        }

        /// <summary>
        /// Gets the order by its id
        /// </summary>
        /// <param name="orderId">Id of the order</param>
        /// <param name="language">Language of the text</param>
        /// <returns>OrderFull value</returns>
        public OrderFull GetOrder(long orderId, string language)
        {
            return ServerApp.DAL.OrderService.GetOrder(orderId, language);
        }

        /// <summary>
        /// Reserves the order (changes its status)
        /// </summary>
        /// <param name="orderId">order id</param>
        /// <param name="executorId">executor id</param>
        /// <returns>new OrderView value</returns>
        public OrderFull ReserveOrder(long orderId, long executorId)
        {
            return ServerApp.DAL.OrderService.ReserveOrder(orderId, executorId);
        }

        /// <summary>
        /// Reserves products for the order
        /// </summary>
        /// <param name="orderId">Id of the order</param>
        /// <param name="productId">Id of the product</param>
        /// <param name="count">number of the products</param>
        /// <returns>difference between number of the order products and real products</returns>
        public int ReserveProduct(long orderId, long productId, int count)
        {
            return ServerApp.DAL.OrderService.ReserveProduct(orderId, productId, count);
        }

        /// <summary>
        /// Updates the order
        /// </summary>
        /// <param name="newOrder">OrderFull value of the order</param>
        /// <returns>OrderFull value of the updated order</returns>
        public OrderFull UpdateOrder(OrderFull newOrder)
        {
            return ServerApp.DAL.OrderService.UpdateOrder(newOrder);
        }

        /// <summary>
        /// Closes the order 
        /// </summary>
        /// <param name="orderId">order id</param>
        /// <returns>new OrderView value</returns>
        public OrderFull CloseOrder(long orderId)
        {
            return ServerApp.DAL.OrderService.CloseOrder(orderId);
        }

        /// <summary>
        /// Cancel the order and unreserves all products of this order
        /// </summary>
        /// <param name="orderId">Id of the order</param>
        /// <returns>bool value</returns>
        public bool CancelOrder(long orderId)
        {
            return ServerApp.DAL.OrderService.CancelOrder(orderId);
        }

        /// <summary>
        /// Add a new product to the order
        /// </summary>
        /// <param name="orderId">Id of the order</param>
        /// <param name="productId">Id of the product</param>
        /// <param name="count">Number of the products</param>
        /// <returns>new OrderFUll value of the current order</returns>
        public OrderFull AddProductToOrder(long orderId, long productId, int count)
        {
            return ServerApp.DAL.OrderService.AddProductToOrder(orderId, productId, count);
        }

        /// <summary>
        /// Delete a product from the current order
        /// </summary>
        /// <param name="orderId">Id of the order</param>
        /// <param name="productId">Id of the product</param>
        /// <param name="count">Number of the products</param>
        /// <returns>new OrderFUll value of the current order</returns>
        public OrderFull DeleteProductFromOrder(long orderId, long productId, int count)
        {
            return ServerApp.DAL.OrderService.DeleteProductFromOrder(orderId, productId, count);
        }

        #endregion

        #region Customer

        public User Login(string login, string password, int? placeId)
        {
            User result = User.Null;
            result = CustomerService.GetUser(login, password, placeId);
            return result;
        }

        public User GetUser(long id)
        {
            User result = User.Null;
            result = CustomerService.GetUser(id);
            return result;
        }

        public User SetUser(User user)
        {
            User result = null;

            if (user.Id == 0)
            {
                result = CustomerService.Add(user);
            }
            else
            {
                result = CustomerService.Update(user);
            }

            return result;
        }

        public bool DeleteUser(User user)
        {
            bool result = false;

            try
            {
                CustomerService.Delete(user);
                result = true;
            }
            catch (Exception)
            { }

            return result;
        }

        public Dictionary<long, User> GetUserList(Dictionary<string, object> filter, int page = 0)
        {
            Dictionary<long, User> result = null;
            result = CustomerService.GetList(filter, page);
            return result;
        }

        #endregion

        #region Producer

        public int AddProducer(ExternalProducerView externalProducer, List<long> productList)
        {
            return ProducerService.AddProducer(externalProducer, productList);
        }

        public int UpdateProducer(Producer producer)
        {
            return ProducerService.UpdateProducer(producer);
        }

        public int DeleteProducer(Producer producer)
        {
            return ProducerService.DeleteProducer(producer);
        }

        public List<ExternalProducerView> GetProducers()
        {
            return ProducerService.GetProducers();
        }

        #endregion Producer

        public void Test()
        {
            Producer p = new Producer();
            ProducerService.UpdateProducer(p);
        }

        #region Category

        public int? GetCountOfCategoryPages(int categoryId, int productOnPage)
        {
            return ProductService.GetCategoryCountPages(categoryId, productOnPage);
        }

        public List<CategoryView> GetCategories(string language, int? parentId = null)
        {
            return ProductService.GetCategories(parentId, language);
        }

        public List<CategoryView> GetCategoriesOfProducer(string language, int producerId, int? parentId = null)
        {
            return ProductService.GetCategoriesOfProducer(parentId, language, producerId);
        }

        public CategoryView GetCtegoryById(int productCategoryId, string currentLanguage)
        {
            return ProductService.GetCategoryViewById(productCategoryId, currentLanguage);
        }

        public CategoryAll GetCategoryAllById(int productCategoryId)
        {
            return ProductService.GetCategoryAllById(productCategoryId);
        }

        public bool DeleteCtegory(int productCategoryId)
        {
            return ProductService.DeleteCategory(productCategoryId);
        }

        public CategoryAll UpdateCtegory(CategoryAll categoryAll)
        {
            return ProductService.UpdateCategory(categoryAll);
        }

        public CategoryAll AddCtegory(CategoryAll categoryAll)
        {
            return ProductService.AddCategory(categoryAll);
        }

        #endregion END Category

        #region Product

        public List<ProductView> GetProductsOnPage(int productCategoryId, string currentLanguage, ProductSort productSort, int page, int countOnPage, Dictionary<ProductFilter, object> filters = null)
        {
            return ProductService.GetProductsOnPage(productCategoryId, currentLanguage, productSort, page, countOnPage, filters);
        }

        public ProductFull GetProductFullById(long productId, string currentLanguage)
        {
            return ProductService.GetProductById(productId, currentLanguage);
        }

        public bool DeleteProduct(long productId)
        {
            return ProductService.DeleteProduct(productId);
        }

        public ProductAll AddProduct(ProductAll productAll)
        {
            return ProductService.AddProduct(productAll);
        }

        public ProductAll UpdateProduct(ProductAll productAll)
        {
            return ProductService.UpdateProduct(productAll);
        }

        public ProductAll GetProductAllById(long productAllId)
        {
            return ProductService.GetProductAllById(productAllId);
        }

        public List<ProductView> GetAllProductsOfProducer(int producerId, string currentLanguage)
        {
            return ProductService.GetAllProductsOfProducer(producerId, currentLanguage);
        }

        #endregion END Product

        #region Product Item

        public ProductItemModel GetProductItemById(long productItemId)
        {
            return ProductService.GetProductItemById(productItemId);
        }

        public ProductItemModel AddProductItem(ProductItemModel productItemModel)
        {
            return ProductService.AddProductItem(productItemModel);
        }

        public ProductItemModel UpdateProductItem(ProductItemModel productItemModel)
        {
            return ProductService.UpdateProductItem(productItemModel);
        }

        public bool DeleteProductItem(long productItemId)
        {
            return ProductService.DeleteProductItem(productItemId);
        }

        #endregion END Product Item

        #region Places

        public List<PlaceView> GetPlaces(string language)
        {
            return PlaceService.GetPlaces(language);
        }

        public PlaceAll GetPlaceAll(int placeAllId)
        {
            return PlaceService.GetPlaceAll(placeAllId);
        }

        public PlaceAll GetPlaceAllByName(string placeName)
        {
            return PlaceService.GetPlaceAll(placeName);
        }

        public PlaceAll AddPlace(PlaceAll placeAll)
        {
            return PlaceService.AddPlace(placeAll);
        }

        public PlaceAll UpdatePlace(PlaceAll placeAll)
        {
            return PlaceService.UpdatePlace(placeAll);
        }

        public bool DeletePlace(int placeId)
        {
            return PlaceService.DeletePlace(placeId);
        }

        public PlaceLocalizationModel GetPlaceLocalizationModelTest()
        {
            return null;
        }

        #endregion END Places
    }//class
}